﻿#include"PostProcessing.h"
using namespace std;
// 后处理类，版本：V2.0
int PostProcessingV2::HuglinesPostProcessing(std::vector<Line>& hugSegments, std::vector<Line>& fixLines, const std::vector<PPObs>& obss) {
	// cout << "miter = " << miter_ << "  \tWireSpacing_ = " << WireSpacing_ << endl;	//====================================================================================
	this->hugSegments_ = hugSegments;
	this->obss_ = &obss;
	std::unordered_set<Line, v2Hash::LineHash> tmpNullLokcLines;
	if (!lockLines_) {	// 防止空指针
		lockLines_ = &tmpNullLokcLines;
	}
	//cout << "PtInObs test===================================================================================================" << endl;
	//Point midPt = (hugSegments[0].Pt1 + hugSegments[0].Pt2) * 0.5;
	//midPt.y = midPt.y - 1.6;
	//for (int step = 0; step < 30; ++step) {
	//	midPt.y = midPt.y + 0.1;
	//	bool inobs = pointInObstacles(midPt, false);
	//	cout << std::fixed << std::setprecision(2) << "P=" << midPt << "\tinside Obs=" << inobs << endl;
	//}
	//return 0;


	// 1.路径预处理
	// 1.1处理宽度为0或端点为nan的线段
	for (size_t i = 0; i < hugSegments_.size(); i++) {
		//处理宽度为0的线段
		if (hugSegments_.at(i).width == 0)
			if (i == 0)
				hugSegments_.at(i).width = 1;
			else
				hugSegments_.at(i).width = hugSegments_.at(i - 1).width;
		//处理端点为nan的线段
		Line* nanLine = &hugSegments_.at(i);
		bool inNan1 = isnan(nanLine->Pt1.x);
		bool inNan2 = isnan(nanLine->Pt1.y);
		bool inNan3 = isnan(nanLine->Pt2.x);
		bool inNan4 = isnan(nanLine->Pt2.y);
		if ((inNan1 || inNan2) && i > 0)
			nanLine->Pt1 = hugSegments_.at(i - 1).Pt2;
		if (inNan3 || inNan4) {
			nanLine->Pt2 = nanLine->Pt1;
			merge((int)i, 0, 2);
		}
	}

	// 1.2确保数据正确
	int hugSegmentsSize = (int)hugSegments_.size();
	if (fixLines.empty() || hugSegments_.empty()) {
		return -1;
	}
	bool spacingSizeErrer = hugSegmentsSize != (int)WireSpacings_.size();
	bool gapSizeErrer = diffInfo_ && hugSegmentsSize != (int)diffInfo_->gaps_.size();
	if (spacingSizeErrer || gapSizeErrer) {
		return -2;
	}

	// 1.2获取hugSegments_中需要处理的线段范围
	setStartAndEndIndex(fixLines);
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -3;
	}

	merge(0, 0, 0);
	// 如果允许扩展边界索引
	if (enlargeBd_) {
		enlargeBoundary();
	}
	//hugSegments = this->hugSegments_; return 0;//==========================================================调试，中途结束并返回

	// 2.最小间距处理
	int while_count = 0;
	bool postRun = true;
	postRun = false;
	bool fixWireSpacing = true;
	while (fixWireSpacing) {
		fixWireSpacing = false;
		for (int i = (startIndex_ > 0 ? startIndex_ - 1 : startIndex_); i + 2 <= (endIndex_ < (int)hugSegments_.size() - 1 ? endIndex_ + 1 : endIndex_); i++) {
			int delete_num = 0;
			////调试阻停位置===================================================================⬇️⬇️⬇️
			/*if (i >= 21 && abs(hugSegments_[0].Pt1.x - 113180184) < 1) {
				cout << "fixWireSpacingi:\ti=" << i << endl;
			}*/
			////===============================================================================⬆️⬆️⬆️
			delete_num = getDeleteLineNum(i);	// 获取小于wirespacing的两条线段之间需要删除的线段数量（此函数内部会修复自交叉走线）
			if (!allowDRCs_ && delete_num != 0 && i + delete_num <= (endIndex_ < (int)hugSegments_.size() - 1 ? endIndex_ + 1 : endIndex_)) {
				//cout << "Wirespacing fix. delete_num= " << delete_num << ",\ti= " << i << endl;	//==============================================================================
				int result = ptToTargetLine(i, i + delete_num, true);		// 往后走线
				if (result == -1) {
					result = ptToTargetLine(i + delete_num, i, true);		// 往前走线
				}
				if (result == -1) {		// 直接将最近点连接起来
					if (delete_num == 3)
						int test01 = 1;
					result = ptToPt(i, i + delete_num);
				}
				if (result > 0) {
					i = merge(result, -2, 2);
					continue;
				}
			}
		}
		if (enlargeBd_) {
			fixWireSpacing = enlargeBoundary();
		}
	}
	//hugSegments = this->hugSegments_; return 0;//==========================================================调试，中途结束并返回
	{
		hugSegmentsSize = (int)hugSegments_.size();
		//索引防御
		if (startIndex_ < 0)
			startIndex_ = 0;
		else if (startIndex_ > hugSegmentsSize - 1)
			startIndex_ = hugSegmentsSize - 1;
		if (endIndex_ < 0)
			endIndex_ = 0;
		else if (endIndex_ > hugSegmentsSize - 1)
			endIndex_ = hugSegmentsSize - 1;
		if (startIndex_ > endIndex_)
			startIndex_ = endIndex_;
		if (hugSegmentsSize != (int)WireSpacings_.size()) {	//检测spaces的数量与hugSegments数量是否相等
			return -4;
		}
		if (diffInfo_) {	//检测gaps的数量与hugSegments数量是否相等
			if (hugSegmentsSize != (int)diffInfo_->gaps_.size()) {
				return -5;
			}
		}
	}

	//3.斜线处理【方案2】，方案1在2024年12月7日的提交中完全删除，要回退需查找之前的记录
	for (int i = startIndex_; i < endIndex_;) {		//i存在后邻居
		//索引防御
		hugSegmentsSize = (int)hugSegments_.size();
		if (i < 0 || i + 1 > hugSegmentsSize) {
			++i;
			continue;
		}
		// lockLines检测
		//bool line_i_is_locked = isLockLine(i);
		bool line_i_is_locked = lockLines_->find(hugSegments_[i]) != lockLines_->end();
		if (line_i_is_locked) {
			++i;
			continue;
		}

		bool notStandartDirection = getDirection(hugSegments_[i]) == -1;
		if (notStandartDirection) {
			int result = fixInclinedLine2(i);
			if (result == -1) {
				++i;
			}
			else {
				i = merge(result, -1, 4);
			}
		}
		else {
			++i;
			continue;
		}
	}
	//hugSegments = this->hugSegments_; return 0;	//==================================================调试，中途结束并返回

	//4.角度与最短线长处理
	hugSegmentsSize = (int)hugSegments_.size();
	if (endIndex_ > hugSegmentsSize - 1)
		endIndex_ = hugSegmentsSize - 1;  // 防止越界，确保endIndex_在范围内

	bool DRCError = true;
	int iterCount = 0;

	while (DRCError && iterCount++ < 60) {
		DRCError = false;
		if (iterCount > 35 && iterCount < 46) {	//多次迭代未结束算法，则将保留的长度放大，加快迭代速度
			remainTimes_ = remainTimes_ + 0.1;
		}
		//4.1尖角处理
		if (fixCuteAngel_) {
			//索引防御
			hugSegmentsSize = (int)hugSegments_.size();
			if (startIndex_ < 0)
				startIndex_ = 0;
			else if (startIndex_ > hugSegmentsSize - 1)
				startIndex_ = hugSegmentsSize - 1;
			if (endIndex_ < 0)
				endIndex_ = 0;
			else if (endIndex_ > hugSegmentsSize - 1)
				endIndex_ = hugSegmentsSize - 1;
			if (startIndex_ > endIndex_)
				startIndex_ = endIndex_;
			if (hugSegmentsSize != (int)WireSpacings_.size()) {	//检测spaces的数量与hugSegments数量是否相等
				return -6;
			}
			if (diffInfo_) {	// 检测gaps的数量与hugSegments数量是否相等
				if (hugSegmentsSize != (int)diffInfo_->gaps_.size()) {
					return -7;
				}
			}
			for (int i = startIndex_; i < endIndex_;) {		//i存在后邻居
				////调试阻停位置===================================================================⬇️⬇️⬇️
				//if (i >= 4) {
				//	int test = 2;
				//	// break;
				//}
				////===============================================================================⬆️⬆️⬆️
				int result = cutAngle(i);
				if (result == -1) {
					++i;
				}
				else {
					//cout << "miter_fix \ti=" << result << endl;		//====================================================
					DRCError = true;
					i = merge(result, -1, 4);
				}
				//索引防御
				hugSegmentsSize = (int)hugSegments_.size();
				if (i < 0 || i + 1 > hugSegmentsSize) {
					++i;
					continue;
				}
			}
		}
		//hugSegments = this->hugSegments_; return 0;	//==================================================调试，中途结束并返回
		//4.2最短线长处理，（处理小于miter的线段）
		if (fixMiterLine_) {
			//索引防御
			hugSegmentsSize = (int)hugSegments_.size();
			if (startIndex_ < 0)
				startIndex_ = 0;
			else if (startIndex_ > hugSegmentsSize - 1)
				startIndex_ = hugSegmentsSize - 1;
			if (endIndex_ < 0)
				endIndex_ = 0;
			else if (endIndex_ > hugSegmentsSize - 1)
				endIndex_ = hugSegmentsSize - 1;
			if (startIndex_ > endIndex_)
				startIndex_ = endIndex_;
			if (hugSegmentsSize != (int)WireSpacings_.size()) {	//检测spaces的数量与hugSegments数量是否相等
				return -6;
			}
			if (diffInfo_) {	// 检测gaps的数量与hugSegments数量是否相等
				if (hugSegmentsSize != (int)diffInfo_->gaps_.size()) {
					return -7;
				}
			}
			for (int i = startIndex_ + 1; i < endIndex_ && i > startIndex_;) {	// i必然存在前邻居和后邻居

				////调试阻停位置===================================================================⬇️⬇️⬇️
				//if (i >= 4) {
				//	int test = 2;
				//	// break;
				//}
				////===============================================================================⬆️⬆️⬆️
				int result = fixMiterLine(i);
				if (result == -1)
					++i;
				else {
					//cout << "miter_fix \ti=" << result << endl;		//==================================================
					DRCError = true;
					i = merge(result, -2, 2);
				}
				//索引防御
				hugSegmentsSize = (int)hugSegments_.size();
				if (i < 0 || i + 1 > hugSegmentsSize) {
					++i;
					continue;
				}
			}
		}

		//hugSegments = this->hugSegments_; return 0;	//==================================================调试，中途结束并返回
		if (enlargeBd_) {
			DRCError = DRCError || enlargeBoundary();
		}
	}
	hugSegments = this->hugSegments_; return 0;
}
//修复函数
int PostProcessingV2::fixInclinedLine2(int fixLineIndex) {
	//方案2被采纳，并于2025年2月27日提交的版本，删除了fixInclinedLine接口，要恢复，请查找之前的提交记录
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (fixLineIndex < 0 || fixLineIndex >= hugSegmentsSize) {
		return -1;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -1;
	}

	//边界的斜线不处理
	if (fixLineIndex == startIndex_ || fixLineIndex == endIndex_)
		return -1;
	if (fixBdOnly_ && fixLineIndex != boundary1 && fixLineIndex != boundary2)  // 仅处理边界线
		return -1;
	int result = -1;
	Line& fixLine = hugSegments_.at(fixLineIndex);
	if (mustBe135_) {  //【修复所有斜线】
		//1.向前向后求交点
		int step = 0;
		while (step < maxSteps_) {
			step++;
			int targetIndex = fixLineIndex - step;
			if (targetIndex < startIndex_)
				break;
			result = ptToTargetLine(fixLineIndex + 1, targetIndex);	//移动Pt1
			if (result >= 0)	// 修复成功
				break;

			targetIndex = fixLineIndex + step;
			if (targetIndex > endIndex_)
				break;
			result = ptToTargetLine(fixLineIndex - 1, fixLineIndex + step);//移动Pt2
			if (result >= 0)	// 修复成功
				break;
		}
		//2.中间插入点实现斜线修复
		if (result < 0) {		// 修复失败
			result = inclineLineStandard(fixLineIndex - 1, fixLineIndex + 1, fixLine);
		}
		return result;
	}
	int movePtType = getMovePtType(fixLine);
	if(movePtType == 3) { //两个端点都不可移动【全绕障线】
		result = -1;
	}
	else if (movePtType == 0 || movePtType == 10 || movePtType == 13) {    //默认【修复半自由线，跨越线，全自由线】
		//1.向前向后求交点
		int step = 0;
		while (step < maxSteps_) {
			step++;
			int targetIndex = fixLineIndex - step;
			if (targetIndex < startIndex_)
				break;
			result = ptToTargetLine(fixLineIndex + 1, targetIndex);	//移动Pt1
			if (result >= 0)	// 修复成功
				break;
			targetIndex = fixLineIndex + step;
			if (targetIndex > endIndex_)
				break;
			result = ptToTargetLine(fixLineIndex - 1, fixLineIndex + step); //移动Pt2
			if (result >= 0)	// 修复成功
				break;
		}
		//2.中间插入点实现斜线修复
		if (result < 0) {		// 修复失败
			result = inclineLineStandard(fixLineIndex - 1, fixLineIndex + 1, fixLine);
		}
	}
	else if (fixHalfObsLine_) {		//【修复半绕障线】
		if (movePtType == 1) { //移动Pt1
			int step = 0;
			while (step < maxSteps_) {
				step++;
				int targetIndex_front = fixLineIndex - step;
				if (targetIndex_front < startIndex_)
					break;
				result = ptToTargetLine(fixLineIndex + 1, targetIndex_front);
				if (result >= 0)	// 修复成功
					break;
			}
		}
		else if (movePtType == 2) { //移动Pt2
			int step = 0;
			while (step < maxSteps_) {
				step++;
				int targetIndex_back = fixLineIndex + step;
				if (targetIndex_back > endIndex_)
					break;
				result = ptToTargetLine(fixLineIndex - 1, targetIndex_back);
				if (result >= 0)	// 修复成功
					break;
			}
		}
	}
	return result;
}
int PostProcessingV2::ptToTargetLine(int S, int T, bool allowCuteAngle) {
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (S < 0 || S >= hugSegmentsSize || T < 0 || T >= hugSegmentsSize) {
		return -1;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -1;
	}

	//进入此函数前，需确保startIndex_和targetIndex未出界
	//0.预处理，计算探索的起点，探索的方向
	int dirArray[3]; //探索的3个标准方向的方向索引
	Point pt;
	bool finding_back = true;		// 向后探索，默认为向后
	Line& sLine = hugSegments_.at(S);		// 起始线段
	dirArray[0] = getNearistDirection(sLine);		// 起始线段最接近的标准方向，向后探索则保持该方向，向前探索则取相反方向
	if (S < T) {
		pt = sLine.Pt2;
	}
	else {
		pt = sLine.Pt1;
		dirArray[0] = (dirArray[0] + 4) % 8;
		finding_back = false;
	}
	dirArray[1] = (dirArray[0] + 1) % 8;
	dirArray[2] = (dirArray[0] + 7) % 8;
	for (int dirction_index : dirArray) {
		Point vec = direc_[dirction_index];
		Point veck = hugSegments_.at(T).getVector() / hugSegments_.at(T).getLength();	// 目标线段的单位方向向量
		Point crossingPt;
		Line newLine;
		//1.不平行，求交点
		if (abs(cross(vec, veck)) > AngleMaxValue) {
			Line l_temp(pt, pt + vec);
			crossingPt = hugSegments_.at(T).getCrossingPoint(l_temp);
		}
		else
			continue;
		//2.根据交点的位置，确定走线方案
		bool crosingPtInTarget = pointInLine(crossingPt, hugSegments_.at(T), true);  //交点在线段 targetIndex 上
		if (crosingPtInTarget) {			//交点在【目标线段】上
			Point endPt = finding_back ? hugSegments_.at(T).Pt2 : hugSegments_.at(T).Pt1;
			bool closeToEndPoint = linearDist(crossingPt, endPt) < sLine.width;
			if (closeToEndPoint)
				newLine = Line(pt, crossingPt);  //距离端点太近，小于线宽，暂时忽略这种特殊情况
			else
				newLine = Line(pt, crossingPt);
		}
		else {
			continue;
		}
		//3.交点在线段上，继续判断选中的走线方案是否可行
		// 3.1 连线与目标线段夹角小于90度，不采纳
		if (allowCuteAngle)  // 允许锐角（解决线间距的DRC问题是，需要允许锐角，后面再对锐角进行处理）
			;
		else {  //不允许锐角
			if ((finding_back ? vec : vec * -1) * veck < -AngleMaxValue) {	//是锐角，小于89.5度，跳过
				//cout << "连线与目标线段夹角不超过90度，不解决" << endl;
				continue;
			}
		}
		// 3.2 连线穿过障碍物，不采纳
		if (lineInObstacles(newLine)) {
			//cout << "连线穿过障碍物，不解决" << endl;
			continue;
		}
		//4.走向同向而不能反向(反向说明在射线vec的反向延长线上)，按连线走线，删除多余的线
		if (newLine.getVector() * vec > 0) {
			//cout << "走线不穿过障碍物,解决" << endl;
			int result = -1;
			if (finding_back)  //往后寻找的情况下的处理方案
			{
				//维护走线
				bool line_S1_is_lockLine = lockLines_->find(hugSegments_[S + 1]) != lockLines_->end();	//设置lockLines
				bool line_T_is_lockLine = lockLines_->find(hugSegments_[T]) != lockLines_->end();		//设置lockLines
				hugSegments_.at(S + 1).Pt2 = crossingPt;
				hugSegments_.at(T).Pt1 = crossingPt;
				if (line_S1_is_lockLine) lockLines_->insert(hugSegments_[S + 1]);	//设置lockLines
				if (line_T_is_lockLine) lockLines_->insert(hugSegments_[T]);		//设置lockLines
				hugSegments_.erase(hugSegments_.begin() + S + 2, hugSegments_.begin() + T);
				//维护gaps
				if (diffInfo_) {
					diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + S + 2, diffInfo_->gaps_.begin() + T);
				}
				//维护wireSpaces
				WireSpacings_.erase(WireSpacings_.begin() + S + 2, WireSpacings_.begin() + T);

				endIndex_ = endIndex_ - T + S + 2;
				result = S + 1;
			}
			else  //往前寻找的情况下的处理方案
			{
				//维护走线
				bool line_S1_is_lockLine = lockLines_->find(hugSegments_[S - 1]) != lockLines_->end();	//设置lockLines
				bool line_T_is_lockLine = lockLines_->find(hugSegments_[T]) != lockLines_->end();		//设置lockLines
				hugSegments_.at(S - 1).Pt1 = crossingPt;
				hugSegments_.at(T).Pt2 = crossingPt;
				if (line_S1_is_lockLine) lockLines_->insert(hugSegments_[S - 1]);	//设置lockLines
				if (line_T_is_lockLine) lockLines_->insert(hugSegments_[T]);		//设置lockLines
				hugSegments_.erase(hugSegments_.begin() + T + 1, hugSegments_.begin() + S - 1);
				//维护gaps
				if (diffInfo_) {
					diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + T + 1, diffInfo_->gaps_.begin() + S - 1);
				}
				//维护wireSpaces
				WireSpacings_.erase(WireSpacings_.begin() + T + 1, WireSpacings_.begin() + S - 1);

				endIndex_ = endIndex_ - S + T + 2;
				result = T + 1;
			};
			return result;
		}
		else
			;
	}
	return -1;
}
int PostProcessingV2::cutAngle(int preLineIndex1) {
	//切角并更新范围的终止索引
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (preLineIndex1 < 0 || preLineIndex1 + 2 > hugSegmentsSize) {
		return -1;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -1;
	}
	//进入此函数，需确保preLineIndex1存在后邻居
	Line& line_i = hugSegments_.at(preLineIndex1);
	Line& line_i1 = hugSegments_.at(preLineIndex1 + 1);
	double Lengthi = line_i.getLength();
	double Lengthi1 = line_i1.getLength();
	Point vec_i = line_i.getVector() / Lengthi;
	Point vec_i1 = line_i1.getVector() / Lengthi1;
	double cosAngle = vec_i * vec_i1;
	if (cosAngle < AngleMaxValue) {		//锐角，或直角(向量夹角大于等于90度)
		// lockLnes检测
		//bool line_i_is_locked = isLockLine(i) && isLockLine(i + 1);
		bool line_i_is_locked = lockLines_->find(hugSegments_[preLineIndex1]) != lockLines_->end()
			&& lockLines_->find(hugSegments_[preLineIndex1 + 1]) != lockLines_->end();
		if (line_i_is_locked) {
			return -1;
		}
		cosAngle = -cosAngle;			//转换为锐角的cos值
		double maxWidth = max(line_i.width, line_i1.width);
		double minDistance;				//最短线长
		double minRemainingLength;		//切角后两侧保留的最小长度
		double miterTemp = getMiter(preLineIndex1);

		minDistance = maxWidth * miterTemp;	//最短线长
		minRemainingLength = minDistance * remainTimes_;
		//setMinDistanceMinRemainingLength(minDistance, minRemainingLength, cross(vec_i, vec_i1), maxWidth);

		if (minDistance < MapMinValue) return -1;	//防止意外出现长度为0的线，导致切角距离为0，使函数陷入死循环

		bool is45Angle = abs(cosAngle - sqrt(2) / 2) < CountMinValue;
		if (is45Angle) {	// 45度切角
			double moveLength_1 = minDistance * (1 + sqrt(2));			
			double moveLength = min({ moveLength_1, Lengthi, Lengthi1 });	
			if (moveLength == moveLength_1) {	
				if (Lengthi - moveLength < minRemainingLength || Lengthi1 - moveLength < minRemainingLength) {
					moveLength = min(Lengthi, Lengthi1);
					minDistance = moveLength * (sqrt(2) - 1);
				}
				Point p1 = line_i.Pt2 - vec_i * moveLength;		//第一个点
				Point p2 = p1 + vec_i * minDistance * sqrt(2) + vec_i1 * minDistance;	//中间点
				Point p3 = line_i1.Pt1 + vec_i1 * moveLength;	//第二个点
				Line lineInsert1 = Line(p1, p2);
				Line lineInsert2 = Line(p2, p3);
				if (lineInObstacles(lineInsert1) || lineInObstacles(lineInsert2)) {
					return -1;		// 穿过障碍物，则不采纳
				}
				//lineInsert1.width = maxWidth;  // 多线宽-->取最大值
				//lineInsert2.width = maxWidth;  // 多线宽-->取最大值
				lineInsert1.width = line_i.width;  // 多线宽-->取左侧值
				lineInsert2.width = line_i.width;  // 多线宽-->取左侧值
				//维护走线
				bool line_i_is_locked = lockLines_->find(line_i) != lockLines_->end();			//设置lockLines
				bool line_i1_is_locked = lockLines_->find(line_i1) != lockLines_->end();	//设置lockLines
				line_i.Pt2 = p1;
				line_i1.Pt1 = p3;
				if (line_i_is_locked) lockLines_->insert(line_i);		//设置lockLines
				if (line_i1_is_locked) lockLines_->insert(line_i1);		//设置lockLines
				hugSegments_.insert(hugSegments_.begin() + preLineIndex1 + 1, lineInsert1);
				hugSegments_.insert(hugSegments_.begin() + preLineIndex1 + 2, lineInsert2);
				//维护gaps
				if (diffInfo_) {
					double gap_value = diffInfo_->gaps_[preLineIndex1 + 1];
					diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + preLineIndex1 + 1, gap_value);
					diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + preLineIndex1 + 2, gap_value);
				}
				//维护wireSpaces
				double space_value = WireSpacings_[preLineIndex1 + 1];
				WireSpacings_.insert(WireSpacings_.begin() + preLineIndex1 + 1, space_value);
				WireSpacings_.insert(WireSpacings_.begin() + preLineIndex1 + 2, space_value);

				endIndex_ += 2;
			}
			else if (Lengthi < Lengthi1) {		//长度不足以采用计算值来切角
				double moveLength_max = Lengthi * sqrt(2);
				moveLength = Lengthi1 > moveLength_max ? moveLength_max : Lengthi / sqrt(2);
				Point p3 = line_i1.Pt1 + vec_i1 * moveLength;
				Line line_temp = Line(line_i.Pt1, p3);
				if (lineInObstacles(line_temp)) {
					return -1;
				}
				bool line_i1_is_locked = lockLines_->find(line_i1) != lockLines_->end();	//设置lockLines
				line_i.Pt2 = p3;
				line_i1.Pt1 = p3;
				if (line_i1_is_locked) lockLines_->insert(line_i1);//设置lockLines
			}
			else {
				double moveLength_max = Lengthi1 * sqrt(2);
				moveLength = Lengthi > moveLength_max ? moveLength_max : Lengthi1 / sqrt(2);
				Point p1 = line_i.Pt2 - vec_i * moveLength;
				Line line_temp = Line(p1, line_i1.Pt2);
				if (lineInObstacles(line_temp)) {
					return -1;
				}
				bool line_i_is_locked = lockLines_->find(line_i) != lockLines_->end();	//设置lockLines
				line_i.Pt2 = p1;
				line_i1.Pt1 = p1;
				if (line_i_is_locked) lockLines_->insert(line_i);//设置lockLines
			}
			return preLineIndex1;
		}
		else {		// 其他锐角切角，按照等腰三角形切角
			double moveLength_1 = minDistance / (2 * sqrt((1 - cosAngle) / 2));	
			double moveLength = min({ moveLength_1, Lengthi, Lengthi1 });		
			if (moveLength == moveLength_1 && (Lengthi - moveLength < minRemainingLength || Lengthi1 - moveLength < minRemainingLength)) {
				moveLength = min(Lengthi, Lengthi1);
			}
			Point Pt1 = line_i.Pt2 - vec_i * moveLength;
			Point Pt2 = line_i1.Pt1 + vec_i1 * moveLength;

			Line newLine = Line(Pt1, Pt2);
			if (lineInObstacles(newLine))		//如果穿过障碍物，则不修复
				return -1;
			else {
				//newLine.width = min(line_i.width, line_i1.width);		// 多线宽-->取前后线段更小的width
				newLine.width = line_i.width;   // 多线宽--> 取左侧值
				//维护走线
				bool line_i_is_locked = lockLines_->find(line_i) != lockLines_->end();	//设置lockLines
				bool line_i1_is_locked = lockLines_->find(line_i1) != lockLines_->end();	//设置lockLines
				line_i.Pt2 = Pt1;
				line_i1.Pt1 = Pt2;
				if (line_i_is_locked) lockLines_->insert(line_i);//设置lockLines
				if (line_i1_is_locked) lockLines_->insert(line_i1);//设置lockLines
				hugSegments_.insert(hugSegments_.begin() + 1 + preLineIndex1, newLine);
				//维护gaps
				if (diffInfo_) {
					double gap_value = diffInfo_->gaps_[preLineIndex1 + 1];
					diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + preLineIndex1 + 1, gap_value);
				}
				//维护wireSpaces
				double space_value = WireSpacings_[preLineIndex1 + 1];
				WireSpacings_.insert(WireSpacings_.begin() + preLineIndex1 + 1, space_value);

				endIndex_ += 1;		// 新增了一条线段，需要将截至线段的索引往后移一次
				return preLineIndex1;
			}
		}
	}
	else
		return -1;
}
int PostProcessingV2::fixMiterLine(int fixLineIndex) {
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (fixLineIndex - 1 < 0 || fixLineIndex + 2 > hugSegmentsSize) {
		return -1;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -1;
	}
	// 解决长度小于width * miter的线段，如果存在，则修复，并返回当前处理的线段的索引，如果不存在或无法处理，则返回-1
	Line& preLine = hugSegments_.at(fixLineIndex - 1);
	Line& line_i = hugSegments_.at(fixLineIndex);
	Line& behindLine = hugSegments_.at(fixLineIndex + 1);
	////===========================================================
	//if (fixLineIndex >= 14) {
	//	cout<< "line_i_length="<< line_i.getLength() << endl;
	//}
	////===========================================================

	double minDistance;  // 允许的线段i的最小长度
	double minRemainingLength;
	double miterTemp = getMiter(fixLineIndex);

	minDistance = line_i.width * miterTemp;	//最短线长
	minRemainingLength = minDistance * remainTimes_;

	double preLength = preLine.getLength();
	double Lengthi = line_i.getLength();
	double behindLength = behindLine.getLength();
	Point vec_pre = preLine.getVector() / preLength;
	Point vec_i = line_i.getVector() / Lengthi;
	Point vec_behind = behindLine.getVector() / behindLength;
	//setMinDistanceMinRemainingLength(minDistance, minRemainingLength, cross(vec_pre, vec_behind), line_i.width);
	if (minDistance < MapMinValue) return -1;	//防止意外出现长度为0的线，导致切角距离为0，使函数陷入死循环
	int result = -1;
	if (Lengthi < minDistance - MapMinValue) {  // 线段i过短
		// lockLnes检测
		//bool line_i_is_locked = isLockLine(i);
		bool line_i_is_locked = lockLines_->find(hugSegments_[fixLineIndex - 1]) != lockLines_->end()
			&& lockLines_->find(hugSegments_[fixLineIndex]) != lockLines_->end()
			&& lockLines_->find(hugSegments_[fixLineIndex + 1]) != lockLines_->end();
		if (line_i_is_locked) {
			return -1;
		}
		if (vec_pre * vec_i < CountMinValue || vec_i * vec_behind < CountMinValue)		//排除中间短线与前后成锐角或直角的情况，等处理完锐角后再考虑
			return -1;
		if (abs(vec_pre * vec_behind) < CountMinValue) {	//前后垂直
			//if (vec_pre * vec_i < CountMinValue || vec_i * vec_behind < CountMinValue)		//排除中间短线与前后成锐角或直角的情况，则等处理完锐角后再考虑
			//	return -1;	//移到上面
			if (abs(vec_pre * vec_i - vec_i * vec_behind) < CountMinValue) {  //与前后夹角相等（都为135度）
				double moveLength_1 = (minDistance - Lengthi) / sqrt(2);
				double moveLength = min({ moveLength_1,preLength ,behindLength });
				if (moveLength == moveLength_1 && (preLength - moveLength < minRemainingLength || behindLength - moveLength < minRemainingLength)) {
					moveLength = min(preLength, behindLength);
				}
				Point Pt1 = preLine.Pt2 - vec_pre * moveLength;
				Point Pt2 = behindLine.Pt1 + vec_behind * moveLength;
				Line line_temp = Line(Pt1, Pt2);
				if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
					result = -1;
				}
				else {
					bool line_pre_is_locked = lockLines_->find(preLine) != lockLines_->end();	//设置lockLines
					bool line_behind_is_locked = lockLines_->find(behindLine) != lockLines_->end();	//设置lockLines
					line_i.Pt1 = Pt1;
					line_i.Pt2 = Pt2;
					preLine.Pt2 = Pt1;
					behindLine.Pt1 = Pt2;
					result = fixLineIndex;
					if (line_pre_is_locked) lockLines_->insert(preLine);//设置lockLines
					if (line_behind_is_locked) lockLines_->insert(behindLine);//设置lockLines
				}
			}
			else {  //中间短线为任意方向，则将短线矫正为标准方向
				Point vec_temp = (vec_pre + vec_behind) / sqrt(2);
				if (vec_pre * vec_i < vec_i * vec_behind) {
					Point Pt1 = getInsection(vec_pre, preLine.Pt1, vec_temp, behindLine.Pt1);
					if ((preLine.Pt1 - Pt1) * (preLine.Pt2 - Pt1) > 0 && fixLineIndex - 2 >= startIndex_) {
						//交点在线段preLine的反向延长线上，则将P1改为与preLine起点
						Pt1 = preLine.Pt1;
					}
					Line line_temp = Line(Pt1, behindLine.Pt1);
					if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
						result = -1;
					}
					else {
						bool line_pre_is_locked = lockLines_->find(preLine) != lockLines_->end();	//设置lockLines
						preLine.Pt2 = Pt1;
						line_i.Pt1 = Pt1;
						if (line_pre_is_locked) lockLines_->insert(preLine);//设置lockLines
						result = fixLineIndex - 1;
					}
				}
				else {
					Point Pt2 = getInsection(vec_behind, behindLine.Pt2, vec_temp, preLine.Pt2);
					if ((behindLine.Pt1 - Pt2) * (behindLine.Pt2 - Pt2) > 0 && fixLineIndex + 2 <= endIndex_) {
						//交点在线段behindLine的延长线上，则将P1改为与behindLine终点
						Pt2 = behindLine.Pt2;
					}
					Line line_temp = Line(preLine.Pt2, Pt2);
					if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
						result = -1;
					}
					else {
						bool line_behind_is_locked = lockLines_->find(behindLine) != lockLines_->end();	//设置lockLines
						line_i.Pt2 = Pt2;
						behindLine.Pt1 = Pt2;
						if (line_behind_is_locked) lockLines_->insert(behindLine);//设置lockLines
						result = fixLineIndex;
					}
				}
			}
		}
		else if (abs(cross(vec_pre, vec_behind)) < AngleMaxValue) {		//前一根线与后一根平行，暂时不处理
			result = -1;
		}
		else if (cross(vec_pre, vec_i) * cross(vec_i, vec_behind) > CountMinValue) {		//前一根与后一根不垂直，不平行，但是朝同一边拐弯，即前后线段在短线的同一侧
			if (abs(vec_pre * vec_i - vec_i * vec_behind) < CountMinValue) {  //与前后夹角相等
				double cosAngle = -(vec_pre * vec_behind);
				double sinHalfAngle = sqrt((1 - cosAngle) / 2);
				double moveLength_1 = (minDistance - Lengthi) / (2 * sinHalfAngle);
				double moveLength = min({ moveLength_1,preLength ,behindLength });
				if (moveLength == moveLength_1 && (preLength - moveLength < minRemainingLength || behindLength - moveLength < minRemainingLength)) {
					moveLength = min(preLength, behindLength);
				}
				Point Pt1 = preLine.Pt2 - vec_pre * moveLength;
				Point Pt2 = behindLine.Pt1 + vec_behind * moveLength;
				Line line_temp = Line(Pt1, Pt2);
				if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
					result = -1;
				}
				else {
					bool line_pre_is_locked = lockLines_->find(preLine) != lockLines_->end();	//设置lockLines
					bool line_behind_is_locked = lockLines_->find(behindLine) != lockLines_->end();	//设置lockLines
					line_i.Pt1 = Pt1;
					line_i.Pt2 = Pt2;
					preLine.Pt2 = Pt1;
					behindLine.Pt1 = Pt2;
					if (line_pre_is_locked) lockLines_->insert(preLine);//设置lockLines
					if (line_behind_is_locked) lockLines_->insert(behindLine);//设置lockLines
					result = fixLineIndex;
				}
			}
			else {  //中间短线为任意方向，则将短线矫正为等腰三角形方向，下次迭代再走if分支修复
				Point vec_temp = vec_pre + vec_behind;
				vec_temp = vec_temp / vec_temp.vecLength();
				if (vec_pre * vec_i < vec_i * vec_behind) {
					Point Pt1 = getInsection(vec_pre, preLine.Pt1, vec_temp, behindLine.Pt1);
					if ((preLine.Pt1 - Pt1) * (preLine.Pt2 - Pt1) > 0 && fixLineIndex - 2 >= startIndex_) {
						Pt1 = preLine.Pt1;
					}
					Line line_temp = Line(Pt1, behindLine.Pt1);
					if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
						result = -1;
					}
					else {
						bool line_pre_is_locked = lockLines_->find(preLine) != lockLines_->end();	//设置lockLines
						preLine.Pt2 = Pt1;
						line_i.Pt1 = Pt1;
						if (line_pre_is_locked) lockLines_->insert(preLine);//设置lockLines
						result = fixLineIndex - 1;
					}
				}
				else {
					Point Pt2 = getInsection(vec_behind, behindLine.Pt2, vec_temp, preLine.Pt2);
					if ((behindLine.Pt1 - Pt2) * (behindLine.Pt2 - Pt2) > 0 && fixLineIndex + 2 <= endIndex_) {
						Pt2 = behindLine.Pt2;
					}
					Line line_temp = Line(preLine.Pt2, Pt2);
					if (lineInObstacles(line_temp)) {		//如果穿过障碍物，则不修复
						return -1;
					}
					else {
						bool line_behind_is_locked = lockLines_->find(behindLine) != lockLines_->end();	//设置lockLines
						line_i.Pt2 = Pt2;
						behindLine.Pt1 = Pt2;
						if (line_behind_is_locked) lockLines_->insert(behindLine);//设置lockLines
						result = fixLineIndex;
					}
				}
			}
		}
		else {		// 前一根与后一根不垂直，不平行，且朝不同侧拐弯（或未拐弯），即前后线段分居短线两侧
			result = -1;
		}
	}
	return result;
}
int PostProcessingV2::ptToPt(int S, int T) {
	//S为起始线段索引，T为终止线段索引；将线段S到线段T连接起来
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (S < 0 || S + 1 > hugSegmentsSize || T < 0 || T + 1 > hugSegmentsSize) {
		return -1;
	}
	Line& s_line = hugSegments_.at(S);
	Line& e_line = hugSegments_.at(T);
	//端点连接
	double distance0 = norm(e_line.Pt1 - s_line.Pt1);	// 起点到起点
	double distance1 = norm(e_line.Pt2 - s_line.Pt1);	// 起点到终点
	double distance2 = norm(e_line.Pt1 - s_line.Pt2);	// 终点到起点
	double distance3 = norm(e_line.Pt2 - s_line.Pt2);	// 终点到终点
	double min_distance = min(distance0, min(distance1, min(distance2, distance3)));
	// 1.将距离最近的两个端点连接起来
	int erase_s, erase_e;
	Line newLine;
	if (min_distance == distance0) {		// 起点到起点
		newLine = Line(s_line.Pt1, e_line.Pt1);
		erase_s = S;
		erase_e = T;
	}
	else if (min_distance == distance1) {	// 起点到终点
		newLine = Line(s_line.Pt1, e_line.Pt2);
		erase_s = S;
		erase_e = T + 1;
	}
	else if (min_distance == distance2) {	// 终点到起点
		newLine = Line(s_line.Pt2, e_line.Pt1);
		erase_s = S + 1;
		erase_e = T;
	}
	else if (min_distance == distance3) {	// 终点到终点
		newLine = Line(s_line.Pt2, e_line.Pt2);
		erase_s = S + 1;
		erase_e = T + 1;
	}
	else {
		return -1;
	}
	if (erase_e == hugSegments_.size()) {  //如果erase_e越界，则插入一根长度为0的线段，防止越界
		Point endPt = hugSegments_.back().Pt2;
		Line zeroLine = Line(endPt, endPt);
		zeroLine.width = hugSegments_.back().width;
		//维护走线，此处不需要维护lockLines
		hugSegments_.push_back(zeroLine);
		//维护gaps
		if (diffInfo_) {
			diffInfo_->gaps_.push_back(diffInfo_->gaps_.back());
		}
		//维护wireSpaces
		WireSpacings_.push_back(WireSpacings_.back());

	}
	// 2.矫正为标准方向走线，如果不穿过障碍物，则接受修改
	bool not_standart_direction = getDirection(newLine) == -1;
	int dir = getNearistDirection(newLine);
	Point vec = direc_[dir];
	Point vec_behind = hugSegments_[erase_e].getVector() / hugSegments_[erase_e].getLength();
	Point vect_front(0, 0);
	if (erase_s > 0)
		vect_front = hugSegments_[erase_s - 1].getVector() / hugSegments_[erase_s - 1].getLength();

	if (not_standart_direction) {	// 不是标准方向，需要矫正
		//方法2,2025年2月27日提交的版本，彻底删除了方法1
		//方案2，取坐标差，斜线在起点或者在终点，两种处理方式都计算，取最优方案
		vector<Point> midPts = getInclineLineMidPt(newLine);
		// 处理方式1，靠近起点走水平竖直线
		Point vec1 = midPts[0] - newLine.Pt1;
		vec1 = vec1 / vec1.vecLength();
		Point vec2 = newLine.Pt2 - midPts[0];
		vec2 = vec2 / vec2.vecLength();
		double totalcos1 = vect_front * vec1 + vec2 * vec_behind;

		// 处理方式2，靠近终点走水平竖直线
		vec1 = midPts[1] - newLine.Pt1;
		vec1 = vec1 / vec1.vecLength();
		vec2 = newLine.Pt2 - midPts[1];
		vec2 = vec2 / vec2.vecLength();
		double totalcos2 = vect_front * vec1 + vec2 * vec_behind;

		int midPtID = totalcos1 > totalcos2 ? 0 : 1;
		int midPtID1, midPtID2;
		if (totalcos1 > totalcos2) {  //前后夹角之和越大，说明越平滑，优先级越高
			midPtID1 = 0;
			midPtID2 = 1;
		}
		else {
			midPtID1 = 1;
			midPtID2 = 0;
		}
		Line L1 = Line(newLine.Pt1, midPts[midPtID1]);	// 插入的线段
		Line L2 = Line(midPts[midPtID1], newLine.Pt2);	// 插入的线段
		if (L1.getLength() < MapMinValue || L2.getLength() < MapMinValue) { //update:2025.4.8
			return -1;
		}
		bool boolL1 = lineInObstacles(L1);
		bool boolL2 = lineInObstacles(L2);
		if (lineInObstacles(L1) || lineInObstacles(L2)) {    //穿过障碍物，当前走线方式不可取，换优先级低的方式
			L1 = Line(newLine.Pt1, midPts[midPtID2]);
			L2 = Line(midPts[midPtID2], newLine.Pt2);
		}
		if (lineInObstacles(L1) || lineInObstacles(L2))     //依旧穿过障碍物，走线都不可取，返回-1
			return -1;

		// L1.width = min(s_line.width, e_line.width);  // 多线宽-->宽度取最小宽度
		L1.width = s_line.width;  // 多线宽-->取左侧值
		L2.width = L1.width;
		//维护走线，此处暂时不维护lockLines，如果有需要，后期再维护
		hugSegments_.erase(hugSegments_.begin() + erase_s, hugSegments_.begin() + erase_e);
		hugSegments_.insert(hugSegments_.begin() + erase_s, L1);
		hugSegments_.insert(hugSegments_.begin() + erase_s + 1, L2);
		//维护gaps
		if (diffInfo_) {
			double gap_value = diffInfo_->gaps_[erase_s];
			diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + erase_s, diffInfo_->gaps_.begin() + erase_e);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + erase_s, gap_value);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + erase_s + 1, gap_value);
		}
		//维护wireSpaces
		double space_value = WireSpacings_[erase_s];
		WireSpacings_.erase(WireSpacings_.begin() + erase_s, WireSpacings_.begin() + erase_e);
		WireSpacings_.insert(WireSpacings_.begin() + erase_s, space_value);
		WireSpacings_.insert(WireSpacings_.begin() + erase_s + 1, space_value);


		endIndex_ = endIndex_ - erase_e + erase_s + 2;
		return erase_s;
		//newLine.width = min(s_line.width, e_line.width);
		//inclineLineStandard(erase_s - 1, erase_e, newLine);
	}
	else {		// 是标准方向，不需要矫正
		if (lineInObstacles(newLine)) {
			return -1;
		}
		//newLine.width = min(s_line.width, e_line.width);  // 多线宽-->宽度取最小宽度
		newLine.width = s_line.width;  // 多线宽-->取左侧值
		//维护走线，此处暂时不维护lockLines，如果有需要，后期再维护
		hugSegments_.erase(hugSegments_.begin() + erase_s, hugSegments_.begin() + erase_e);
		hugSegments_.insert(hugSegments_.begin() + erase_s, newLine);
		//维护gaps
		if (diffInfo_) {
			double gap_value = diffInfo_->gaps_[erase_s];
			diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + erase_s, diffInfo_->gaps_.begin() + erase_e);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + erase_s, gap_value);
		}
		//维护wireSpaces
		double space_value = WireSpacings_[erase_s];
		WireSpacings_.erase(WireSpacings_.begin() + erase_s, WireSpacings_.begin() + erase_e);
		WireSpacings_.insert(WireSpacings_.begin() + erase_s, space_value);

		endIndex_ = endIndex_ - erase_e + erase_s + 1;
	}
	//索引防御
	hugSegmentsSize = (int)hugSegments_.size();
	if (startIndex_ < 0)
		startIndex_ = 0;
	else if (startIndex_ > hugSegmentsSize - 1)
		startIndex_ = hugSegmentsSize - 1;
	if (endIndex_ < 0)
		endIndex_ = 0;
	else if (endIndex_ > hugSegmentsSize - 1)
		endIndex_ = hugSegmentsSize - 1;
	if (startIndex_ > endIndex_)
		startIndex_ = endIndex_;

	return erase_s;
}
int PostProcessingV2::inclineLineStandard(int S, int T, Line& line) {
	// 给定斜线的左邻居和右邻居
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (S < 0 || S >= hugSegmentsSize || T < 0 || T >= hugSegmentsSize) {
		return -1;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return -1;
	}
	//确保斜线自身有宽度
	if (line.width < MapMinValue) {
		// line.width = min(hugSegments_[S].width, hugSegments_[T].width);		// 多线宽-->取最小值
		line.width = hugSegments_[S].width;		// 多线宽-->取前面的宽度
	}
	bool isFirstLine = false;
	bool isLastLine = false;
	Point vec_behind(0, 0);
	if (T >= 0 && T < hugSegmentsSize)
		vec_behind = hugSegments_[T].getVector() / hugSegments_[T].getLength();
	else if (T >= hugSegmentsSize) {
		T = hugSegmentsSize - 1;	//越界则置为最后一个，用于后续删除使用
		isLastLine = true;
	}
	else if (T < 0)
		return -1;	//理论上没有这种情况
	Point vect_front(0, 0);
	if (S >= 0 && S < hugSegmentsSize)
		vect_front = hugSegments_[S].getVector() / hugSegments_[S].getLength();
	else if (S >= hugSegmentsSize)
		return -1;	//理论上没有这种情况
	else if (S < 0) {
		S = 0;						//越界则置0，用于后续插入和删除使用
		isFirstLine = true;
	}
	//取坐标差，斜线在起点或者在终点，两种处理方式都计算，取最优方案
	vector<Point> midPts = getInclineLineMidPt(line);
	// 处理方式1，靠近起点走水平竖直线
	Point vec1 = midPts[0] - line.Pt1;
	vec1 = vec1 / vec1.vecLength();
	Point vec2 = line.Pt2 - midPts[0];
	vec2 = vec2 / vec2.vecLength();
	double totalcos1 = vect_front * vec1 + vec2 * vec_behind;

	// 处理方式2，靠近终点走水平竖直线
	vec1 = midPts[1] - line.Pt1;
	vec1 = vec1 / vec1.vecLength();
	vec2 = line.Pt2 - midPts[1];
	vec2 = vec2 / vec2.vecLength();
	double totalcos2 = vect_front * vec1 + vec2 * vec_behind;

	int midPtID = totalcos1 > totalcos2 ? 0 : 1;
	int midPtID1, midPtID2;
	if (totalcos1 > totalcos2) {  //前后夹角之和越大，说明越平滑，优先级越高
		midPtID1 = 0;
		midPtID2 = 1;
	}
	else {
		midPtID1 = 1;
		midPtID2 = 0;
	}

	Line L1 = Line(line.Pt1, midPts[midPtID1]);	// 插入的线段
	Line L2 = Line(midPts[midPtID1], line.Pt2);	// 插入的线段
	if (L1.getLength() < MapMinValue || L2.getLength() < MapMinValue) { //update:2025.4.8
		return -1;
	}
	if (lineInObstacles(L1) || lineInObstacles(L2)) {    //穿过障碍物，当前走线方式不可取，换优先级低的方式
		L1 = Line(line.Pt1, midPts[midPtID2]);
		L2 = Line(midPts[midPtID2], line.Pt2);
	}
	if (lineInObstacles(L1) || lineInObstacles(L2))     //依旧穿过障碍物，走线都不可取，返回-1
		return -1;

	L1.width = line.width;
	L2.width = line.width;
	if (!isFirstLine && !isLastLine) {		//不是首段或末段，即传入的原始S，T均未出界
		//维护走线，此处暂时不维护lockLines，如果有需要，后期再维护
		hugSegments_.erase(hugSegments_.begin() + S + 1, hugSegments_.begin() + T);
		hugSegments_.insert(hugSegments_.begin() + S + 1, L1);
		hugSegments_.insert(hugSegments_.begin() + S + 2, L2);
		//维护gaps
		if (diffInfo_) {
			double gap_value = diffInfo_->gaps_[S];
			diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + S + 1, diffInfo_->gaps_.begin() + T);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + S + 1, gap_value);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + S + 2, gap_value);
		}
		//维护wireSpaces
		double space_value = WireSpacings_[S];
		WireSpacings_.erase(WireSpacings_.begin() + S + 1, WireSpacings_.begin() + T);
		WireSpacings_.insert(WireSpacings_.begin() + S + 1, space_value);
		WireSpacings_.insert(WireSpacings_.begin() + S + 2, space_value);

		endIndex_ = endIndex_ - T + S + 3;
	}
	else if (isFirstLine) {	//首段
		//维护走线，此处暂时不维护lockLines，如果有需要，后期再维护
		hugSegments_.erase(hugSegments_.begin());
		hugSegments_.insert(hugSegments_.begin(), L1);
		hugSegments_.insert(hugSegments_.begin() + 1, L2);
		startIndex_ = 0;
		//维护gaps
		if (diffInfo_) {
			double gap_value = diffInfo_->gaps_[0];
			diffInfo_->gaps_.erase(diffInfo_->gaps_.begin());
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin(), gap_value);
			diffInfo_->gaps_.insert(diffInfo_->gaps_.begin() + 1, gap_value);
		}
		//维护wireSpaces
		double space_value = WireSpacings_[0];
		WireSpacings_.erase(WireSpacings_.begin());
		WireSpacings_.insert(WireSpacings_.begin(), space_value);
		WireSpacings_.insert(WireSpacings_.begin() + 1, space_value);

		endIndex_ = endIndex_ + 1;
	}
	else if (isLastLine) {	//末段
		//维护走线，此处暂时不维护lockLines，如果有需要，后期再维护
		hugSegments_.pop_back();
		hugSegments_.push_back(L1);
		hugSegments_.push_back(L2);
		//维护gaps
		if (diffInfo_) {
			diffInfo_->gaps_.push_back(diffInfo_->gaps_.back());
		}
		//维护wireSpaces
		WireSpacings_.push_back(WireSpacings_.back());
		endIndex_ = endIndex_ + 1;
	}
	return S;
}
//辅助函数
bool PostProcessingV2::isLockLine(int i) {

	for (auto lockLine = lockLines_->begin(); lockLine != lockLines_->end(); lockLine++) {
		bool Pt1EqualPt1 = abs(hugSegments_[i].Pt1.x - lockLine->Pt1.x) <= MapMinValue && abs(hugSegments_[i].Pt1.y - lockLine->Pt1.y) <= MapMinValue;
		bool Pt2EqualPt2 = abs(hugSegments_[i].Pt2.x - lockLine->Pt2.x) <= MapMinValue && abs(hugSegments_[i].Pt2.y - lockLine->Pt2.y) <= MapMinValue;
		bool Pt1EqualPt2 = abs(hugSegments_[i].Pt1.x - lockLine->Pt2.x) <= MapMinValue && abs(hugSegments_[i].Pt1.y - lockLine->Pt2.y) <= MapMinValue;
		bool Pt2EqualPt1 = abs(hugSegments_[i].Pt2.x - lockLine->Pt1.x) <= MapMinValue && abs(hugSegments_[i].Pt2.y - lockLine->Pt1.y) <= MapMinValue;
		bool lineEqual = (Pt1EqualPt1 && Pt2EqualPt2) || (Pt1EqualPt2 && Pt2EqualPt1);
		if (lineEqual) {
			return true;
		}
	}
	return false;

}
vector<Point> PostProcessingV2::getInclineLineMidPt(Line& inclineLine) {
	//调用此函数，说明inclineLine本身不是8个标准方向，获取一个中间点，将该线变成两段标准方向的走线
	// 处理方式1，靠近起点走水平竖直线；处理方式2，靠近终点走水平竖直线
	double x1 = inclineLine.Pt1.x;
	double y1 = inclineLine.Pt1.y;
	double x2 = inclineLine.Pt2.x;
	double y2 = inclineLine.Pt2.y;
	double dx = x2 - x1;
	double dy = y2 - y1;
	double abs_dx = abs(dx);
	double abs_dy = abs(dy);
	double  mid_x1, mid_y1, mid_x2, mid_y2;	    //两种改线方式的中间点
	if (abs_dy > abs_dx) {		//dy更大，坐标差取dx
		int step_y = dy > 0 ? 1 : -1;
		mid_x1 = x1;
		mid_y1 = y2 - abs_dx * step_y;
		mid_x2 = x2;
		mid_y2 = y1 + abs_dx * step_y;
	}
	else {
		int step_x = dx > 0 ? 1 : -1;
		mid_y1 = y1;
		mid_x1 = x2 - abs_dy * step_x;
		mid_y2 = y2;
		mid_x2 = x1 + abs_dy * step_x;
	}
	vector<Point> result = { Point(mid_x1, mid_y1) ,Point(mid_x2, mid_y2) };
	return result;
}
double PostProcessingV2::getMiter(int i) {
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (i < 0 || i + 1 > hugSegmentsSize) {
		return miter_;
	}
	if (diffInfo_) {
		double miterTemp = diffInfo_->getMiterEnlarged(i, miter_, hugSegments_.at(i).width);
		Point veci = hugSegments_.at(i).getVector() / hugSegments_.at(i).getLength();
		if (i > 0 && i + 1 < hugSegmentsSize) {  //线段有左右邻居
			Point veci_1 = hugSegments_.at(i - 1).getVector() / hugSegments_.at(i - 1).getLength();
			Point veci1 = hugSegments_.at(i + 1).getVector() / hugSegments_.at(i + 1).getLength();
			bool verticalAngle = abs(veci_1 * veci1) < CountMinValue;
			bool needToEnlargeMiter = diffInfo_->dir_ == cross(veci_1, veci1) > 0;	//左侧，逆时针需放大；右侧，顺时针，需放大
			if (verticalAngle && needToEnlargeMiter)		//前一根与后一根垂直，才需要考虑是否放大miter
				return miterTemp;
			else
				return miter_;
		}
		else if (i == 0 || i + 1 == hugSegmentsSize) {	//线段是首段或末段，进行放大，以便边界扩展
			return miter_;
		}
		else
			return miter_;	//出界
	}
	else
		return miter_;
}
void PostProcessingV2::setMinDistanceMinRemainingLength(double& minDistance, double& minRemainingLength, const double& crossValue, const double& maxWidth) {
	//如果切角的线为差分线，需要根据不同的角度类型，采取不同的miter值,计算最短线长minDistance和切角后保留的最小长度minRemainingLength
	// @minDistance: 最短线长
	// @minRemainingLength: 切角后保留的最小长度
	// @crossValue: 两边单位化后的向量叉乘值，用于判断顺时针还是逆时针
	// @maxWidth: 线宽

	//if (diffInfo_)
	//	if (diffInfo_->dir_ == (crossValue > 0)) {	//逆时针方向且在锐角内侧，或者顺时针且在锐角外侧，需要将miter放大为miterTimes_倍
	//		minDistance = maxWidth * miter_ * diffInfo_->miterTimes_;
	//		minRemainingLength = minDistance * remainTimes_;
	//		return;
	//	}
	minDistance = maxWidth * miter_;	//最短线长
	minRemainingLength = minDistance * remainTimes_;
}
void PostProcessingV2::setStartAndEndIndex(std::vector<Line>& fixLines) {	// 获取待处理线段的索引范围，第一根的前一根到最后一根的后一根
	startIndex_ = -1;
	endIndex_ = -1;
	int fixLine_index_temp = 0;
	int hugSegmentsSize = (int)hugSegments_.size();
	while (startIndex_ == -1 && fixLine_index_temp < (int)fixLines.size()) {
		Line& line1 = fixLines[fixLine_index_temp];
		for (int i = 0; i < hugSegmentsSize; i++) {
			Line& line2 = hugSegments_.at(i);

			//bool lineIsSame = line1.Pt1 == line2.Pt1 && line1.Pt2 == line2.Pt2;
			//bool lineIsSame_r = line1.Pt1 == line2.Pt2 && line1.Pt2 == line2.Pt1;
			//if (lineIsSame || lineIsSame_r) {
			//	startIndex_ = i;
			//	break;
			//}

			bool Pt11_XIsSame = abs(line1.Pt1.x - line2.Pt1.x) < MapMinValue;
			bool Pt11_YIsSame = abs(line1.Pt1.y - line2.Pt1.y) < MapMinValue;
			bool Pt22_XIsSame = abs(line1.Pt2.x - line2.Pt2.x) < MapMinValue;
			bool Pt22_YIsSame = abs(line1.Pt2.y - line2.Pt2.y) < MapMinValue;
			bool lineIsSame = Pt11_XIsSame && Pt11_YIsSame && Pt22_XIsSame && Pt22_YIsSame;

			bool Pt12_XIsSame = abs(line1.Pt1.x - line2.Pt2.x) < MapMinValue;
			bool Pt12_YIsSame = abs(line1.Pt1.y - line2.Pt2.y) < MapMinValue;
			bool Pt21_XIsSame = abs(line1.Pt2.x - line2.Pt1.x) < MapMinValue;
			bool Pt21_YIsSame = abs(line1.Pt2.y - line2.Pt1.y) < MapMinValue;
			bool lineIsSame_r = Pt11_XIsSame && Pt11_YIsSame && Pt22_XIsSame && Pt22_YIsSame;

			if (lineIsSame || lineIsSame_r) {
				startIndex_ = i;
				break;
			}
		}
		if (startIndex_ >= 0)
			break;
		else
			fixLine_index_temp++;
	}
	fixLine_index_temp = (int)fixLines.size() - 1;
	while (endIndex_ == -1 && fixLine_index_temp >= 0) {
		Line& line1 = fixLines[fixLine_index_temp];
		for (int i = hugSegmentsSize - 1; i >= 0; i--) {
			Line& line2 = hugSegments_.at(i);

			bool Pt11_XIsSame = abs(line1.Pt1.x - line2.Pt1.x) < MapMinValue;
			bool Pt11_YIsSame = abs(line1.Pt1.y - line2.Pt1.y) < MapMinValue;
			bool Pt22_XIsSame = abs(line1.Pt2.x - line2.Pt2.x) < MapMinValue;
			bool Pt22_YIsSame = abs(line1.Pt2.y - line2.Pt2.y) < MapMinValue;
			bool lineIsSame = Pt11_XIsSame && Pt11_YIsSame && Pt22_XIsSame && Pt22_YIsSame;

			bool Pt12_XIsSame = abs(line1.Pt1.x - line2.Pt2.x) < MapMinValue;
			bool Pt12_YIsSame = abs(line1.Pt1.y - line2.Pt2.y) < MapMinValue;
			bool Pt21_XIsSame = abs(line1.Pt2.x - line2.Pt1.x) < MapMinValue;
			bool Pt21_YIsSame = abs(line1.Pt2.y - line2.Pt1.y) < MapMinValue;
			bool lineIsSame_r = Pt11_XIsSame && Pt11_YIsSame && Pt22_XIsSame && Pt22_YIsSame;

			if (lineIsSame || lineIsSame_r) {
				endIndex_ = i;
				break;
			}
		}
		if (endIndex_ >= 0)
			break;
		else
			fixLine_index_temp--;
	}
	boundary1 = startIndex_ + 1;
	boundary2 = endIndex_ - 1;
	startIndex_ -= SEIndexMoveSteps_;
	endIndex_ += SEIndexMoveSteps_;

	//索引防御
	if (startIndex_ < 0)
		startIndex_ = 0;
	else if (startIndex_ > hugSegmentsSize - 1)
		startIndex_ = hugSegmentsSize - 1;
	if (endIndex_ < 0)
		endIndex_ = 0;
	else if (endIndex_ > hugSegmentsSize - 1)
		endIndex_ = hugSegmentsSize - 1;
	if (startIndex_ > endIndex_)
		startIndex_ = endIndex_;

}
bool PostProcessingV2::enlargeBoundary() {
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (startIndex_ < 0)
		startIndex_ = 0;
	else if (startIndex_ > hugSegmentsSize - 1)
		startIndex_ = hugSegmentsSize - 1;
	if (endIndex_ < 0)
		endIndex_ = 0;
	else if (endIndex_ > hugSegmentsSize - 1)
		endIndex_ = hugSegmentsSize - 1;
	if (startIndex_ > endIndex_)
		startIndex_ = endIndex_;

	// 当前边界线段过短，或者与边界外的一条线段夹角为直角或锐角，则扩展边界。
	bool moved = false;
	bool smallerThanMiter = false;
	bool isCuteAngle = false;
	//1.移动startIndex_
	double miterTemp = getMiter(startIndex_);
	double miterEnlarge = miterTemp;
	//double miterEnlarge = miterTemp * (sqrt(2) + 1 + remainTimes_);	// 放大最短线长，按照45度切角之后，剩余长度恰好为miterMaxTimes
	Line* sline = &hugSegments_.at(startIndex_);
	bool moveStart = startIndex_ > 0;	//确保存在左邻居
	if (moveStart) {
		Point vec1 = hugSegments_.at(startIndex_ - 1).getVector() / hugSegments_.at(startIndex_ - 1).getLength();
		Point vec2 = sline->getVector() / sline->getLength();
		if (startIndex_ + 1 < hugSegmentsSize) {  //判断跟范围内邻居的夹角，如果是锐角，则需要使用放大的miterEnlarge
			Point vec3 = hugSegments_.at(startIndex_ + 1).getVector() / hugSegments_.at(startIndex_ + 1).getLength();
			double cosAngle = vec2 * vec3;	//与内部邻居的向量夹角，小于0线段夹角为锐角，否则为钝角
			if (cosAngle < AngleMaxValue)	// 45度角取前者，其他锐角或直角取后者
				miterEnlarge = abs(cosAngle + sqrt(2) / 2) < CountMinValue ? miterTemp * (sqrt(2) + 1 + remainTimes_) : miterTemp / (sqrt(2 + 2 * cosAngle));
		}
		smallerThanMiter = sline->getLength() < miterEnlarge * sline->width - MapMinValue;
		isCuteAngle = vec1 * vec2 < AngleMaxValue;
		moveStart = smallerThanMiter || isCuteAngle;
	}
	while (moveStart) {
		startIndex_--;
		moved = true;
		miterTemp = getMiter(startIndex_);
		miterEnlarge = miterTemp;
		//miterEnlarge = miterTemp * (sqrt(2) + 1 + remainTimes_);  // 放大最短线长，按照45度切角之后，剩余长度恰好为miterMaxTimes
		sline = &hugSegments_.at(startIndex_);
		moveStart = startIndex_ > 0;	//确保存在左邻居
		if (moveStart) {
			Point vec1 = hugSegments_.at(startIndex_ - 1).getVector() / hugSegments_.at(startIndex_ - 1).getLength();
			Point vec2 = sline->getVector() / sline->getLength();
			if (startIndex_ + 1 < hugSegmentsSize) {  //判断跟范围内邻居的夹角，如果是锐角，则需要使用放大的miterEnlarge
				Point vec3 = hugSegments_.at(startIndex_ + 1).getVector() / hugSegments_.at(startIndex_ + 1).getLength();
				double cosAngle = vec2 * vec3;	//与内部邻居的向量夹角，小于0线段夹角为锐角，否则为钝角
				if (cosAngle < AngleMaxValue)	// 45度角取前者，其他锐角或直角取后者
					miterEnlarge = abs(cosAngle + sqrt(2) / 2) < CountMinValue ? miterTemp * (sqrt(2) + 1 + remainTimes_) : miterTemp / (sqrt(2 + 2 * cosAngle));
			}
			smallerThanMiter = sline->getLength() < miterEnlarge * sline->width - MapMinValue;
			isCuteAngle = vec1 * vec2 < AngleMaxValue;
			moveStart = smallerThanMiter || isCuteAngle;
		}
	}

	//2.移动endIndex_
	miterTemp = getMiter(endIndex_);
	miterEnlarge = miterTemp;
	//miterEnlarge = miterTemp * (sqrt(2) + 1 + remainTimes_);  // 放大最短线长，按照45度切角之后，剩余长度恰好为miterMaxTimes
	Line* eline = &hugSegments_.at(endIndex_);
	bool moveEnd = endIndex_ + 1 < hugSegmentsSize;	//确保存在右邻居
	if (moveEnd) {
		Point vec1 = eline->getVector() / eline->getLength();
		Point vec2 = hugSegments_.at(endIndex_ + 1).getVector() / hugSegments_.at(endIndex_ + 1).getLength();
		if (endIndex_ > 0) {  //判断跟范围内邻居的夹角，如果是锐角，则需要使用放大的miterEnlarge
			Point vec0 = hugSegments_.at(endIndex_ - 1).getVector() / hugSegments_.at(endIndex_ - 1).getLength();
			double cosAngle = vec0 * vec1;	//与内部邻居的向量夹角，小于0线段夹角为锐角，否则为钝角
			if (cosAngle < AngleMaxValue)	// 45度角取前者，其他锐角或直角取后者
				miterEnlarge = abs(cosAngle + sqrt(2) / 2) < CountMinValue ? miterTemp * (sqrt(2) + 1 + remainTimes_) : miterTemp / (sqrt(2 + 2 * cosAngle));
		}
		smallerThanMiter = eline->getLength() < miterEnlarge * eline->width - MapMinValue;
		isCuteAngle = vec1 * vec2 < AngleMaxValue;
		moveEnd = smallerThanMiter || isCuteAngle;
	}
	while (moveEnd) {
		endIndex_++;
		moved = true;
		miterTemp = getMiter(endIndex_);
		miterEnlarge = miterTemp;
		//miterEnlarge = miterTemp * (sqrt(2) + 1 + remainTimes_);  // 放大最短线长，按照45度切角之后，剩余长度恰好为miterMaxTimes
		eline = &hugSegments_.at(endIndex_);
		moveEnd = endIndex_ + 1 < hugSegmentsSize;	//确保存在右邻居
		if (moveEnd) {
			Point vec1 = eline->getVector() / eline->getLength();
			Point vec2 = hugSegments_.at(endIndex_ + 1).getVector() / hugSegments_.at(endIndex_ + 1).getLength();
			if (endIndex_ > 0) {  //判断跟范围内邻居的夹角，如果是锐角，则需要使用放大的miterEnlarge
				Point vec0 = hugSegments_.at(endIndex_ - 1).getVector() / hugSegments_.at(endIndex_ - 1).getLength();
				double cosAngle = vec0 * vec1;	//与内部邻居的向量夹角，小于0线段夹角为锐角，否则为钝角
				if (cosAngle < AngleMaxValue)	// 45度角取前者，其他锐角或直角取后者
					miterEnlarge = abs(cosAngle + sqrt(2) / 2) < CountMinValue ? miterTemp * (sqrt(2) + 1 + remainTimes_) : miterTemp / (sqrt(2 + 2 * cosAngle));
			}
			smallerThanMiter = eline->getLength() < miterEnlarge * eline->width - MapMinValue;
			isCuteAngle = vec1 * vec2 < AngleMaxValue;
			moveEnd = smallerThanMiter || isCuteAngle;
		}
	}

	//索引防御
	if (startIndex_ < 0)
		startIndex_ = 0;
	else if (startIndex_ > hugSegmentsSize - 1)
		startIndex_ = hugSegmentsSize - 1;
	if (endIndex_ < 0)
		endIndex_ = 0;
	else if (endIndex_ > hugSegmentsSize - 1)
		endIndex_ = hugSegmentsSize - 1;
	if (startIndex_ > endIndex_)
		startIndex_ = endIndex_;

	return moved;
}
int PostProcessingV2::getDeleteLineNum(int i) {
	// 获取小于wirespacing的两条线段之间需要删除的线段数量（此函数内部会修复自交叉走线）
	//索引防御
	int hugSegmentsSize = (int)hugSegments_.size();
	if (i < 0 || i + 1 > hugSegmentsSize) {
		return 0;
	}
	if (startIndex_ < 0 || endIndex_ >= hugSegmentsSize || startIndex_ > endIndex_) {
		return 0;
	}
	int deleteLinesSum = 0;  //要删除的线段数量
	for (int j = i + 2; j <= (endIndex_ < (int)hugSegments_.size() - 1 ? endIndex_ + 1 : endIndex_); j++) {
		if (hugSegments_.at(j).State == 1)
			continue;
		double distance = getTwoLinesDist(hugSegments_.at(i), hugSegments_.at(j));
		double wirespacing = max(WireSpacings_[i], WireSpacings_[j]);
		double minDistance = wirespacing + 0.5 * (hugSegments_.at(i).width + hugSegments_.at(j).width);
		Point veci = hugSegments_.at(i).getVector() / hugSegments_.at(i).getLength();
		Point vecj = hugSegments_.at(j).getVector() / hugSegments_.at(j).getLength();
		bool is_parallel = abs(cross(veci, vecj)) < AngleMaxValue;
		if (distance == 0 && !is_parallel) {	//线段相交，且不平行
			Line l_temp = hugSegments_.at(j);
			Point crossingPt = hugSegments_.at(i).getCrossingPoint(l_temp);
			//维护走线
			bool line_i_is_locked = lockLines_->find(hugSegments_.at(i)) != lockLines_->end();	//设置lockLines
			bool line_j_is_locked = lockLines_->find(hugSegments_.at(j)) != lockLines_->end();	//设置lockLines
			hugSegments_.at(i).Pt2 = crossingPt;
			hugSegments_.at(j).Pt1 = crossingPt;
			if (line_i_is_locked) lockLines_->insert(hugSegments_.at(i));		//设置lockLines
			if (line_j_is_locked) lockLines_->insert(hugSegments_.at(j));		//设置lockLines
			hugSegments_.erase(hugSegments_.begin() + i + 1, hugSegments_.begin() + j);
			//维护gaps
			if (diffInfo_) {
				diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i + 1, diffInfo_->gaps_.begin() + j);
			}
			//维护wireSpaces
			WireSpacings_.erase(WireSpacings_.begin() + i + 1, WireSpacings_.begin() + j);
			endIndex_ = endIndex_ - j + i + 1;
			// 若前面或者后面的线段长度为0，则删除，并更新endIndex_
			if (hugSegments_.at(i).getLength() < MapMinValue) {
				if (i == 0)
					hugSegments_.at(i).Pt2 = hugSegments_.at(i).Pt1;
				else
					hugSegments_.at(i - 1).Pt2 = hugSegments_.at(i).Pt2;
				//维护走线，此处不需要维护lockLines
				hugSegments_.erase(hugSegments_.begin() + i);
				//维护gaps
				if (diffInfo_) {
					diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i);
				}
				//维护wireSpaces
				WireSpacings_.erase(WireSpacings_.begin() + i);

				endIndex_--;
			}
			hugSegmentsSize = (int)hugSegments_.size();
			if ((i + 1) < hugSegmentsSize && hugSegments_.at(i + 1).getLength() < MapMinValue) {//线段i长度为0，删除
				hugSegments_.at(i).Pt2 = hugSegments_.at(i + 1).Pt2;
				//维护走线，此处不需要维护lockLines
				hugSegments_.erase(hugSegments_.begin() + i + 1);
				//维护gaps
				if (diffInfo_) {
					diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i + 1);
				}
				//维护wireSpaces
				WireSpacings_.erase(WireSpacings_.begin() + i + 1);
				endIndex_--;
			}
			j = i + 2;
			deleteLinesSum = 0;
		}
		else if (distance < minDistance - MapMinValue) {
			deleteLinesSum = j - i;
		}
	}
	if (deleteLinesSum == 2) {
		double distance = getTwoLinesDist(hugSegments_.at(i), hugSegments_.at(i + 2));
		double lengthi1 = hugSegments_.at(i + 1).getLength();
		double tolorance = CountMinValue;
		//double tolorance = distance > 1000 ? MapMinValue : CountMinValue;		//根据数据的数量级设置容差值
		if (abs(distance - lengthi1) < tolorance)	//2024.12.4update,将MapMinValue改为CountMinValue
			return 0;
		else
			return 2;
	}
	else
		return deleteLinesSum;
}
int PostProcessingV2::getMovePtType(Line& line) {
	//返回值说明：
	// -1:数据异常
	// 0:【半自由线】，两个端点都可移动（平行共线，且两个端点都不在障碍物端点）
	// 1:【半绕障线】只能移动Pt1（平行共线，且仅Pt2与障碍物端点重合）
	// 2:【半绕障线】只能移动Pt2（平行共线，且仅Pt1与障碍物端点重合）
	// 3:【全绕障线】两个端点都不可移动（平行共线，且两个点都与障碍物端点重合）
	// 10:【跨越线】（不共线，且两个端点都不与障碍物端点重合，完全自由的线）
	// 13:【全自由线】（不共线，且两个点都与障碍物端点重合）
	int result = -1;
	result = obss_->empty() ? 10 : 0;
	double lineLength = line.getLength();
	if (lineLength < MapMinValue)	//长度为0，数据异常，返回-1
		return -1;
	Point vecLine = line.getVector() / lineLength;
	for (int i = 0; i < obss_->size(); i++) {
		double min_Lx = min(line.Pt1.x, line.Pt2.x);	//走线线段的外包盒
		double max_Lx = max(line.Pt1.x, line.Pt2.x);
		double min_Ly = min(line.Pt1.y, line.Pt2.y);
		double max_Ly = max(line.Pt1.y, line.Pt2.y);
		if (obss_->at(i).xMax_ < min_Lx - MapMinValue || obss_->at(i).xMin_ > max_Lx + MapMinValue || obss_->at(i).yMax_ < min_Ly - MapMinValue || obss_->at(i).yMin_ > max_Ly + MapMinValue)
			continue;		// 利用障碍物外包盒对障碍物进行过滤
		for (int j = 0; j < obss_->at(i).olines->size(); j++) {
			Line& obs_line = obss_->at(i).olines->at(j);
			Point& pObs1 = obs_line.Pt1;
			Point& pObs2 = obs_line.Pt2;
			double min_obsLx = min(pObs1.x, pObs2.x);	//障碍物线段的外包盒
			double max_obsLx = max(pObs1.x, pObs2.x);
			double min_obsLy = min(pObs1.y, pObs2.y);
			double max_obsLy = max(pObs1.y, pObs2.y);
			if (min_Lx > max_obsLx + MapMinValue || max_Lx < min_obsLx - MapMinValue || min_Ly > max_obsLy + MapMinValue || max_Ly < min_obsLy - MapMinValue)
				continue;		// 利用障碍物线段外包盒对障碍物线段进行过滤
			// 障碍物上的线段的单位向量
			Point vecObsLine(0, 0);
			double vecObsLineLength = obs_line.getLength();
			if (vecObsLineLength > MapMinValue)
				vecObsLine = obs_line.getVector() / vecObsLineLength;
			else
				continue;	// 跳过障碍物上长度为0的线段
			//障碍物端点到当前线段的端点形成的向量
			Point vecpt1ToLinePt1(0, 0);
			double length = vecpt1ToLinePt1.vecLength();
			if (length > MapMinValue)
				vecpt1ToLinePt1 = (line.Pt1 - obs_line.Pt1) / vecpt1ToLinePt1.vecLength();  //单位化

			//if平行且重合,分类0-3，否则分类10-13
			bool isParallel = abs(cross(vecLine, vecObsLine)) < AngleMaxValue;				//平行
			bool lineCoincide = abs(cross(vecpt1ToLinePt1, vecObsLine)) < AngleMaxValue;	//共线
			if (isParallel && lineCoincide) {  //线段line与障碍物上的线段平行
				bool coincidePt1 = line.Pt1 == obs_line.Pt1 || line.Pt1 == obs_line.Pt2;    // line起点重合
				bool coincidePt2 = line.Pt2 == obs_line.Pt1 || line.Pt2 == obs_line.Pt2;    // line终点重合
				if (coincidePt1 && coincidePt2)
					return 3;
				else if (coincidePt1 && !coincidePt2)
					return 2;
				else if (!coincidePt1 && coincidePt2)
					return 1;
				else
					return 0;	// 两个端点都不重合的线
			}
			else {		//1.平行不共线，2.不平行不共线，3.不平行共线（不存在）
				bool coincidePt1 = line.Pt1 == obs_line.Pt1 || line.Pt1 == obs_line.Pt2;    // line起点重合
				bool coincidePt2 = line.Pt2 == obs_line.Pt1 || line.Pt2 == obs_line.Pt2;    // line终点重合
				if (coincidePt1 && coincidePt2)
					result = 13;	// 不共线，但起点终点重合，未实现
				else
					result = 10;	// 不共线，两个端点都可移动的线
			}
		}
	}
	return result;
}
//8个标准方向,x轴方向编号为0，逆时针顺序，xy正方向角平分线编号为1，y轴正方向编号为2
const vector<Point> PostProcessingV2::direc_ = { Point(1,0),Point(sqrt(2) / 2,sqrt(2) / 2),
			Point(0,1), Point(-sqrt(2) / 2,sqrt(2) / 2), Point(-1,0),
			Point(-sqrt(2) / 2,-sqrt(2) / 2), Point(0,-1),
			Point(sqrt(2) / 2,-sqrt(2) / 2) };  //8个标准方向
//删除index1到index2范围内（包含首尾），长度为0的线段，合并相邻共线的线段
int PostProcessingV2::merge(int index, int range1 = 0, int range2 = 0) {
	if (index < 0)
		return 0;
	//预处理，设定本次待处理的索引范围
	int index1 = index + range1;
	int index2 = index + range2;
	if (index1 > index2)	//起点索引大于终点索引
		return index;
	else if (index1 == index2) {		//说明传入的前后范围相等，即2个range都为默认值0，则merge全部线段
		index1 = startIndex_;
		index2 = endIndex_;
	}

	if (index1 < 0)
		index1 = 0;
	int hugsegmentsSize = (int)hugSegments_.size();
	if (index2 >= hugsegmentsSize)
		index2 = hugsegmentsSize - 1;

	//删除长度为0的线段，合并相邻且共线的线段
	for (int i = index1; i + 1 <= index2;) {		//确保i+1不出界
		Point veci = hugSegments_.at(i).getVector();
		double Lengthi = hugSegments_.at(i).getLength();
		Point veci1 = hugSegments_.at(i + 1).getVector();
		double Lengthi1 = hugSegments_.at(i + 1).getLength();
		if (Lengthi < MapMinValue) {					//线段i长度为0，删除
			if (i == 0)
				hugSegments_.at(i + 1).Pt1 = hugSegments_.at(i).Pt1;
			else
				hugSegments_.at(i - 1).Pt2 = hugSegments_.at(i).Pt2;
			//维护走线，此处不需要维护lockLines
			hugSegments_.erase(hugSegments_.begin() + i);
			//维护gaps
			if (diffInfo_) {
				diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i);
			}
			//维护wireSpaces
			WireSpacings_.erase(WireSpacings_.begin() + i);

			if (i <= index)
				index = index > 0 ? index - 1 : 0;
			if (i <= startIndex_) {
				index2--;
				startIndex_ = startIndex_ > 0 ? startIndex_ - 1 : 0;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else if (i <= endIndex_) {
				index2--;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else {
				index2--;
			}
		}
		else if (Lengthi1 < MapMinValue) {			//线段i+1长度为0，删除，MapMinValue
			hugSegments_.at(i).Pt2 = hugSegments_.at(i + 1).Pt2;
			//维护走线，此处不需要维护lockLines
			hugSegments_.erase(hugSegments_.begin() + i + 1);
			//维护gaps
			if (diffInfo_) {
				diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i + 1);
			}
			//维护wireSpaces
			WireSpacings_.erase(WireSpacings_.begin() + i + 1);

			if (i + 1 <= index)
				index = index > 0 ? index - 1 : 0;
			if (i + 1 <= startIndex_) {
				index2--;
				startIndex_ = startIndex_ > 0 ? startIndex_ - 1 : 0;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else if (i + 1 <= endIndex_) {
				index2--;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else {
				index2--;
			}
		}
		else if (abs(cross(veci / Lengthi, veci1 / Lengthi1)) < AngleMaxValue
			&& hugSegments_.at(i).width == hugSegments_.at(i + 1).width) {	//线段i与线段i+1长度均不为0，但共线，并且宽度相等，合并AngleMaxValue

			//维护走线
			bool mergedLine_is_locked = lockLines_->find(hugSegments_.at(i)) != lockLines_->end()  //设置lockLines
				|| lockLines_->find(hugSegments_.at(i + 1)) != lockLines_->end(); //设置lockLines
			hugSegments_.at(i).Pt2 = hugSegments_.at(i + 1).Pt2;
			if (mergedLine_is_locked) lockLines_->insert(hugSegments_.at(i));		//设置lockLines

			hugSegments_.erase(hugSegments_.begin() + i + 1);
			//维护gaps
			if (diffInfo_) {
				diffInfo_->gaps_.erase(diffInfo_->gaps_.begin() + i + 1);
			}
			//维护wireSpaces
			WireSpacings_.erase(WireSpacings_.begin() + i + 1);

			if (i < index) {
				index = index > 0 ? index - 1 : 0;
			}
			if (i < startIndex_) {
				index2--;
				startIndex_ = startIndex_ > 0 ? startIndex_ - 1 : 0;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else if (i < endIndex_) {
				index2--;
				endIndex_ = endIndex_ > startIndex_ ? endIndex_ - 1 : startIndex_;
			}
			else {
				index2--;
			}
		}
		else
			i++;
	}
	if (index < startIndex_) index = startIndex_;
	if (index > endIndex_) index = endIndex_;
	return index;
}
int PostProcessingV2::getDirection(Line line) {  //判断line是否为8个标准方向之一
	Point vec = line.getVector() / line.getLength();
	for (int i = 0; i < 4; i++) {
		Point vecStandard = direc_.at(i);
		if (abs(cross(vecStandard, vec)) < AngleMaxValue)  //共线AngleMaxValue
			if (vecStandard * vec > AngleMaxValue)  //同向AngleMaxValue
				return  i;
			else  //反向
				return i + 4;
	}
	return -1;
}
int PostProcessingV2::getNearistDirection(Line line) {  //判断line是否为8个标准方向之一
	Point vec = line.getVector() / line.getLength();
	double vec_dire_value = vec * direc_[0];
	int dire = 0;
	for (int k = 1; k < 8; k++) {
		double temp = vec * direc_[k];
		if (temp >= vec_dire_value) {  //取内积最大的，作为标准方向
			vec_dire_value = temp;
			dire = k;
		}
	}
	return dire;
}
//判断线段是否与障碍物有交点。线段line端点在障碍物上，认为与障碍物没有交点。有交点返回true
bool PostProcessingV2::lineInObstacles(Line& line) {
	//cout << "lineInObstacles3执行·········" << endl;
	int crosingPtsNum = 0;
	Point vecLine = line.getVector();
	for (int i = 0; i < obss_->size(); i++) {
		double min_Lx = min(line.Pt1.x, line.Pt2.x);	//走线线段的外包盒
		double max_Lx = max(line.Pt1.x, line.Pt2.x);
		double min_Ly = min(line.Pt1.y, line.Pt2.y);
		double max_Ly = max(line.Pt1.y, line.Pt2.y);
		if (obss_->at(i).xMax_ < min_Lx - MapMinValue || obss_->at(i).xMin_ > max_Lx + MapMinValue || obss_->at(i).yMax_ < min_Ly - MapMinValue || obss_->at(i).yMin_ > max_Ly + MapMinValue)
			continue;		// 利用障碍物外包盒对障碍物进行过滤
		std::vector<Point> mids;	// 将line分成多段的中间点
		for (int j = 0; j < obss_->at(i).olines->size(); j++) {
			Line& obs_line = obss_->at(i).olines->at(j);
			Point& pObs1 = obs_line.Pt1;
			Point& pObs2 = obs_line.Pt2;
			double min_obsLx = min(pObs1.x, pObs2.x);	//障碍物线段的外包盒
			double max_obsLx = max(pObs1.x, pObs2.x);
			double min_obsLy = min(pObs1.y, pObs2.y);
			double max_obsLy = max(pObs1.y, pObs2.y);
			if (min_Lx > max_obsLx + MapMinValue || max_Lx < min_obsLx - MapMinValue || min_Ly > max_obsLy + MapMinValue || max_Ly < min_obsLy - MapMinValue)
				continue;		// 利用障碍物线段外包盒对障碍物线段进行过滤
			if (abs(cross(vecLine / norm(vecLine), obs_line.getVector() / norm(obs_line))) > AngleMaxValue) {  //线段line与障碍物上的线段不平行，求交点
				Point crosingPoint = line.getCrossingPoint(obs_line);
				bool crosingPointInObs = pointInLine(crosingPoint, obs_line, false);		//交点在障碍物线段中部，不含端点
				bool crosingPointInLine = pointInLine(crosingPoint, line, false);			//交点在line上，且不在line的端点处
				if (crosingPointInObs) {	//交点在障碍物线段中部，不含端点（传false）
					if (crosingPointInLine)			//交点在line中间，而不是line端点（传false），为有效交点
					{
						crosingPtsNum++;
					}
				}
				else {						//交点不在障碍物线段上
					bool inVertex = norm(obs_line.Pt1 - crosingPoint) < MapMinValue || norm(obs_line.Pt2 - crosingPoint) < MapMinValue;
					if (inVertex && crosingPointInLine) {		// 交点在障碍物顶点上，且在线段line内部
						mids.emplace_back(crosingPoint);
					}
				}
			}
		}
		if (!mids.empty()) {		//存在分割点
			bool isInside = false;
			Point* pt_temp = &line.Pt1;
			for (auto& pt : mids) {
				isInside = pointInObstacles((*pt_temp + pt) * 0.5, false);
				if (isInside)
					return true;
				else
					pt_temp = &pt;
			}
			isInside = pointInObstacles((*pt_temp + line.Pt2) * 0.5, false);
			if (isInside)
				return true;
		}
	}
	if (crosingPtsNum == 0)		 //没有交点，整个线段可能在多边形内部，也可能在外部，也可能与障碍物边重合，取中点
		return pointInObstacles((line.Pt1 + line.Pt2) * 0.5, false);
	else  //有交点
		return true;
}
bool PostProcessingV2::lineInObstacles1(Line& line) {
	//cout << "lineInObstacles执行·········" << endl;
	vector<Point> crosingPts;
	Point vecLine = line.getVector();
	for (int i = 0; i < obss_->size(); i++) {

		double min_Lx = min(line.Pt1.x, line.Pt2.x);	//走线线段的外包盒
		double max_Lx = max(line.Pt1.x, line.Pt2.x);
		double min_Ly = min(line.Pt1.y, line.Pt2.y);
		double max_Ly = max(line.Pt1.y, line.Pt2.y);
		if (obss_->at(i).xMax_ < min_Lx || obss_->at(i).xMin_ > max_Lx || obss_->at(i).yMax_ < min_Ly || obss_->at(i).yMin_ > max_Ly)
			continue;		// 利用障碍物外包盒对障碍物进行过滤
		for (int j = 0; j < obss_->at(i).olines->size(); j++) {
			Line& lineObs = obss_->at(i).olines->at(j);
			Point& pObs1 = lineObs.Pt1;
			Point& pObs2 = lineObs.Pt2;
			double min_obsLx = min(pObs1.x, pObs2.x);	//障碍物线段的外包盒
			double max_obsLx = max(pObs1.x, pObs2.x);
			double min_obsLy = min(pObs1.y, pObs2.y);
			double max_obsLy = max(pObs1.y, pObs2.y);
			if (min_Lx > max_obsLx || max_Lx < min_obsLx || min_Ly > max_obsLy || max_Ly < min_obsLy)
				continue;		// 利用障碍物线段外包盒对障碍物线段进行过滤
			if (abs(cross(vecLine / norm(vecLine), lineObs.getVector() / norm(lineObs))) > AngleMaxValue) {  //线段line与障碍物上的线段不平行，求交点
				Point crosingPoint = line.getCrossingPoint(lineObs);
				Point vec1 = (pObs1 - crosingPoint) / norm(lineObs);
				Point vec2 = (pObs2 - crosingPoint) / norm(lineObs);
				Point vec3 = (line.Pt1 - crosingPoint) / norm(line);
				Point vec4 = (line.Pt2 - crosingPoint) / norm(line);
				double vec12 = vec1 * vec2;
				bool crosingPointInObs = vec12 < -CountMinValue;				//交点在障碍物线段中部，不含端点
				bool crosingPointInLine = vec3 * vec4 < -CountMinValue;			//交点在line上，且不在line的端点处
				if (crosingPointInObs)
					if (crosingPointInLine)	//交点在line中间，而不是line端点，为有效交点
					{
						// cout << "在中间 = " << crosingPointInLine << endl;
						crosingPts.push_back(crosingPoint);
					}
			}
		}
	}
	if (crosingPts.empty())		 //没有交点，整个线段可能在多边形内部，也可能在外部，也可能与障碍物边重合，取中点
		return pointInObstacles((line.Pt1 + line.Pt2) * 0.5, false);
	else  //有交点
		return true;
}
bool PostProcessingV2::pointInObstacles(Point p, bool polygonIncludeOutline) {		//判断点是否在障碍物内部
	bool isInside = false;
	for (int i = 0; i < obss_->size(); i++) {
		int crossing_num = 0;
		for (const Line& obs_line : *obss_->at(i).olines) {
			const Point& p1 = obs_line.Pt1;
			const Point& p2 = obs_line.Pt2;
			double min_y = min(p1.y, p2.y);
			double max_y = max(p1.y, p2.y);
			double min_x = min(p1.x, p2.x);
			double max_x = max(p1.x, p2.x);
			if (p.y >= min_y && p.y < max_y) {
				if (max_y - min_y < MapMinValue) {		// obs_line是水平线(接近水平线)
					if (p.x < min_x - MapMinValue)
						++crossing_num;
					else if (p.x < max_x + MapMinValue)
						return polygonIncludeOutline;
					else
						continue;
				}
				else {			// obs_line不是水平线
					double x = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
					if (abs(p.x - x) < MapMinValue)	// 交点与p重合，p在边界上
						return polygonIncludeOutline;
					if (x > p.x)
						++crossing_num;
				}
			}
		}
		if (crossing_num % 2 == 1) {
			isInside = true;
			break;
		}
	}
	return isInside;
}
bool PostProcessingV2::pointInObstacles1(Point p) {		//判断点是否在障碍物内部
	bool retry = true;
	vector<Point> crosingPts;
	int n = 0;
	while (retry && n < 10) {
		retry = false;
		crosingPts.clear();
		n++;
		Point vec_d(1, 0.1 * n);		//取一个任意方向(1, 0.1)-->(1, 1)，递增0.1
		for (int i = 0; i < obss_->size(); i++) {
			for (int j = 0; j < obss_->at(i).olines->size() && !retry; j++) {
				Line line = obss_->at(i).olines->at(j);
				//if(line.Pt1.x == 127527631.478659)
					//cout << line.Pt1.x << endl;
				Point vec = line.getVector() / line.getLength();
				if (abs(cross(vec_d, vec)) > AngleMaxValue) {		//不平行
					Line l_temp(p, p + vec_d);
					Point crosingPoint = line.getCrossingPoint(l_temp);
					if (crosingPoint == p) {
						return false;
					}
					if (pointInLine(crosingPoint, line, false) && (crosingPoint - p) * vec_d > CountMinValue) {	//交点在障碍物线段上，且交点在p的vec射线方向，交点可以与p重合
						if (crosingPts.size() == 0)			//有效的交点
							crosingPts.push_back(crosingPoint);
						else if (crosingPoint == crosingPts.front() || crosingPoint == crosingPts.back()) {		//该交点再次出现（交点刚好在障碍物顶点）
							// 重新选取一个射线方向，重新求交点个数
							retry = true;
							break;
						}
						else	// 该交点是新出现的交点
							crosingPts.push_back(crosingPoint);
					}
				}
			}
		}
		if (!retry)		//交点不在障碍物端点处，则结束while循环
			break;
	}
	if (crosingPts.size() % 2 == 1)  //射线交点个数为奇数，说明p在内部
		return true;
	else
		return false;
}
bool PostProcessingV2::pointInObstacles2(Point p, bool polygonIncludeOutline) {		//判断点是否在障碍物内部
	bool isInside = false;
	for (int i = 0; i < obss_->size(); i++) {
		int crossing_num = 0;
		for (const Line& obs_line : *obss_->at(i).olines) {
			const Point& p1 = obs_line.Pt1;
			const Point& p2 = obs_line.Pt2;
			if (abs(p1.y - p2.y) < MapMinValue) {	// y相同，obs_line是水平线
				bool xInMid = (p.x > std::min(p1.x, p2.x) - MapMinValue) && (p.x <= std::max(p1.x, p2.x) + MapMinValue);
				if (abs(p.y - p1.y) < MapMinValue && xInMid)  // p在水平线obs_line上
					return polygonIncludeOutline;
				else
					continue;
			}
			if (p.y < std::min(p1.y, p2.y) - MapMinValue)
				continue;
			if (p.y >= std::max(p1.y, p2.y) - MapMinValue)
				continue;
			double x = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
			if (abs(p.x - x) < MapMinValue)	// 交点与p重合，p在边界上
				return polygonIncludeOutline;
			if (p.x < x)
				crossing_num++;
		}
		if (crossing_num % 2 == 1) {
			isInside = true;
			break;
		}
	}
	return isInside;
}
bool PostProcessingV2::pointInLine(Point p, Line line, bool lineIncludeVertex) {		//已知p在直线line上，判断在不在线段上，在端点或距离端点很近，认为在线段上
	// lineIncludeVertex = true 表示线段包含两个端点，即p在端点上时认为p在线段上
	if (norm(line.Pt1 - p) < MapMinValue || norm(line.Pt2 - p) < MapMinValue)	//p在端点上
		return lineIncludeVertex;
	else if ((line.Pt1 - p) * (line.Pt2 - p) <= 0)
		return true;
	else
		return false;
}
